package com.menxin.queueImpl;

/**
 * Created by Menx on 2019/3/7.
 */
@SuppressWarnings("unchecked")
public class LoopArrayQueue<E> implements Queue<E> {

    private E[] data;
    private int head;
    private int tail;
    private int size;

    public LoopArrayQueue(int capacity) {
        data = (E[]) new Object[capacity + 1];
        head = 0;
        tail = 0;
        size = 0;
    }

    public LoopArrayQueue() {
        this(10);
    }


    @Override
    public void add(E e) {
        if ((tail + 1) % data.length == head) {
            resize((data.length - 1) * 2 + 1);
        }
        data[tail] = e;
        tail = (tail + 1) % data.length;
        size++;
    }

    @Override
    public E remove() {
        E e = data[head];
        data[head] = null;
        head = (head + 1) % data.length;
        size--;
        if (size < getCapcatiy() / 4 && getCapcatiy() / 2 != 0) {
            resize(getCapcatiy() / 2);
        }
        return e;
    }

    @Override
    public int getCapcatiy() {
        return data.length - 1;
    }

    @Override
    public boolean isEmpty() {
        return tail == head;
    }

    private void resize(int capacity) {
        E[] newData = (E[]) new Object[capacity];
        for (int i = 0; i < size; i++) {
            newData[i] = data[(head + i) % data.length];
        }
        head = 0;
        tail = size;
        data = newData;
    }

    @Override
    public E getFront() {
        return data[head];
    }

    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append("LoopArrayQueue Head[");
        for (int i = 0; i < size; i++) {
            buf.append(data[(head + i) % data.length]);
            if (i < size - 1) {
                buf.append(",");
            }
        }
        buf.append("]Tail");
        return buf.toString();
    }
}
